xlv.obj.select={
	extend:function(){
	},
	implement:function(){
		this.implement('xlv.imp.mvc');
		this.implement('xlv.imp.editor');		
	},
	create:function(tag){
		var div=document.createElement((tag||'div'));
		div.setAttribute('xlvobject','xlv.obj.select');
		Element.addClassName(div,'class_select');
		return div;					 
	},
	properties:{
		dmName:null,
		dmPath:null,
		lookupdmName:null,
		lookupdmPath:null,
		lookupdmTextPath:null,
		lookupdmMoveTo:false,
		multiple:null,
		size:null
	},
	method:{
		construct:function(){
			Element.addClassName(this,'class_select');
			var v=this.$V;
			v.editor=xlv.util.isTag(this,'select')?this:xlv.util.findDirectChild(this,{tag:'select'});
			if(!v.editor){
				v.editor=document.createElement('select');
				this.appendChild(v.editor);
			}
			if(this.$P.multiple) v.editor.setAttribute('MULTIPLE','true');
			if(this.$P.size!==null) v.editor.setAttribute('size',''+this.$P.size);
			this.styleFor(v.editor);
		},
		initial:function(){
			this.addEventHandler('change', '_change',this.$V.editor);
			this.$V.lookupReady=(this.$P.lookupdmName)?false:true;
		},
		styleFor:function(editor){
		},
		_change:function(event){
			var v=this.$V;
			var dm;
			if(dm=this.mvc_getModel(this.$P.dmName)){
				this.mvc_valueToModel(v.editor.options[v.editor.selectedIndex].value,dm);
			}
			if(this.$P.lookupdmMoveTo==true){
				dm=this.mvc_getModel(this.$P.lookupdmName);
				if(dm && v.editor.selectedIndex>=0)dm.position(v.editor.selectedIndex+1);
			}
		},
		_refreshOptions:function(dm){
			
			var v=this.$V;
			dm=(dm||this.mvc_getModel(this.$P.lookupdmName));
			var rows=dm.rows();
			var options=v.editor.options;
			for(var i=options.length-1;i>=0;--i)options[i]=null;
			for(var i=0;i<rows;++i){
				v.editor.appendChild(document.createElement('option'));
				var row=dm.getRow(i+1);
				if(dm.isUpdatedRow(row))Element.addClassName(options[i],'updated');
				if(dm.isRemovedRow(row))Element.addClassName(options[i],'removed');
				if(dm.isInsertedRow(row))Element.addClassName(options[i],'inserted');
				Element.addClassName(options[i],(i%2)==0? 'even':'odd');
				this.valueForOption(dm,i,options[i]);
				this.styleForOption(i,options[i]);
			}
			v.lookupReady=true;
			if(this.$V.defer_editor_valueToEditor) {
				this.$V.defer_editor_valueToEditor();
				this.$V.defer_editor_valueToEditor=null;
			}
		},
		styleForOption:function(index,option){
		},
		valueForOption:function(dm,index,option){
			var value=this.mvc_valueFromModel(dm,index);
			option.value=value;
			option.text=value;
			if(this.$P.lookupdmTextPath!=null)
				option.text=dm.map(this.$P.lookupdmPath,value,this.$P.lookupdmTextPath);
		},
		_isModel:function(dm){
			return this.$P.dmName==dm.getName();
		},
		_isLookupModel:function(dm){
			return this.$P.lookupdmName==dm.getName();
		},
		mvc_isModel:function(dm){
			return (this._isModel(dm)||this._isLookupModel(dm));
		},
		mvc_addListener:function(){
			var dm;
			if(dm=this.mvc_getModel(this.$P.dmName))dm.addListener(this);
			if(dm=this.mvc_getModel(this.$P.lookupdmName))dm.addListener(this);
		},
		mvc_removeListener:function(){
			var dm;
			if(dm=this.mvc_getModel(this.$P.dmName))dm.removeListener(this);
			if(dm=this.mvc_getModel(this.$P.lookupdmName))dm.removeListener(this);
		},
		mvc_valueFromModel:function(dm,index){
			if(this._isModel(dm)) return dm.getValue(this.$P.dmPath);
			if(this._isLookupModel(dm)) return dm.getValue(this.$P.lookupdmPath,index+1);
			return null;
		},
		mvc_valueToModel:function(value,dm,index){
			if(this._isModel(dm)) dm.setValue(value,this.$P.dmPath);
			else if(this._isLookupModel(dm))dm.setValue(value,this.$P.lookupdmPath,index+1);
		},
		mvc_beforeModelChanged:function(dm,notify,memo){
		},
		mvc_modelChanged:function(dm,notify,memo){
			switch(notify){
				case 'nodeChanged':
					if(memo.type=='update'){
						if(this._isLookupModel(dm) && this.$P.lookupdmPath && memo.src && this.$P.lookupdmPath.endsWith(memo.src.nodeName)){
							var row_no=dm.rowNumber(memo.src.parentNode);
							var option=this.$V.editor.options[row_no-1];
							this.valueForOption(dm,row_no-1,option);
							Element.addClassName(option,'updated');
						}
						if(this._isModel(dm)&& this.$P.dmPath && memo.src && this.$P.dmPath.endsWith(memo.src.nodeName))
							this.mvc_valueToView(this.mvc_valueFromModel(dm));
					}
					break;
			}
		},
		mvc_afterModelChanged:function(dm,notify,memo){
			switch(notify){
				case 'setChanged' :
					if(this._isLookupModel(dm)) this._refreshOptions(dm);
					if(this._isModel(dm) && this.$V.lookupReady) this.mvc_valueToView(this.mvc_valueFromModel(dm));
					break;
				case 'rowChanged':
					if(this._isLookupModel(dm)) this._refreshOptions(dm);
					if(this._isModel(dm) && memo.type=='cancel') this.mvc_valueToView(this.mvc_valueFromModel(dm));
					break;
				case 'cursorMove' :
					if(this._isModel(dm)) this.mvc_valueToView(this.mvc_valueFromModel(dm));
					break;
			}
			this.mvc_enableControl(dm);
		},
		mvc_enableControl:function(dm){
		},
		mvc_valueToView:function(value){
			this.editor_valueToEditor(value);
		},
		mvc_valueFromView:function(){
			this.editor_valueFromEditor();
		},
		/**editor imp*/
		editor_valueToEditor:function(value){
			if(this.$V.lookupReady){
				var options=this.$V.editor.options;
				for(var i=0;i<options.length;++i){
					if(options[i].value==value){
						this.$V.editor.selectedIndex=i;
						return;
					}
				}
				this.$V.editor.selectedIndex=-1;
			}else this.$V.defer_editor_valueToEditor=(function(){this.editor_valueToEditor(value);}).bind(this);
		},
		editor_valueFromEditor:function(){
			var editor=this.$V.editor;
			return (editor.selectedIndex<0) ? null:editor.options[editor.selectedIndex].value;
		}
	}
};
